home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
postpone.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
8KB
|
330 lines
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mutt.h"
#include "mutt_menu.h"
#include "send.h"
#include "rfc1524.h"
#include "mime.h"
#include "mailbox.h"
#include "parse.h"
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
static short PostCount = 0;
static time_t LastModify = 0;
static CONTEXT *PostContext = NULL;
int mutt_num_postponed (void)
{
struct stat st;
CONTEXT ctx;
if (stat (Postponed, &st) == -1)
{
PostCount = 0;
LastModify = 0;
return (0);
}
else if (S_ISDIR (st.st_mode))
{
/* if we have a maildir mailbox, we need to stat the "new" dir */
char buf[_POSIX_PATH_MAX];
snprintf (buf, sizeof (buf), "%s/new", Postponed);
if (access (buf, F_OK) == 0 && stat (buf, &st) == -1)
{
PostCount = 0;
LastModify = 0;
return 0;
}
}
if (LastModify < st.st_mtime)
{
LastModify = st.st_mtime;
if (access (Postponed, R_OK | F_OK) != 0)
return (PostCount = 0);
if (mx_open_mailbox (Postponed, M_NOSORT | M_QUIET, &ctx) == NULL)
PostCount = 0;
else
PostCount = ctx.msgcount;
mx_fastclose_mailbox (&ctx);
}
return (PostCount);
}
static void post_entry (char *s, size_t slen, MUTTMENU *menu, int entry)
{
char buf[SHORT_STRING] = { 0 };
CONTEXT *ctx = (CONTEXT *) menu->data;
rfc822_write_address (buf, sizeof (buf), ctx->hdrs[entry]->env->to);
snprintf (s, slen, "%2d %c %-20.20s %s",
entry + 1,
ctx->hdrs[entry]->deleted ? 'D' : ' ',
buf,
ctx->hdrs[entry]->env->subject);
}
static HEADER *select_msg (void)
{
MUTTMENU *menu;
int i, done=0, r=-1;
char helpstr[SHORT_STRING];
char tmp[16];
menu = mutt_new_menu ();
menu->make_entry = post_entry;
menu->menu = MENU_POST;
menu->max = PostContext->msgcount;
menu->title = "Postponed Messages";
menu->data = PostContext;
helpstr[0] = 0;
mutt_make_help (tmp, sizeof (tmp), "Exit ", MENU_POST, OP_EXIT);
strcat (helpstr, tmp);
mutt_make_help (tmp, sizeof (tmp), "Del ", MENU_POST, OP_DELETE);
strcat (helpstr, tmp);
mutt_make_help (tmp, sizeof (tmp), "Undel ", MENU_POST, OP_UNDELETE);
strcat (helpstr, tmp);
mutt_make_help (tmp, sizeof (tmp), "Help", MENU_POST, OP_HELP);
strcat (helpstr, tmp);
menu->help = helpstr;
while (!done)
{
switch (i = mutt_menuLoop (menu))
{
case OP_DELETE:
case OP_UNDELETE:
mutt_set_flag (PostContext, PostContext->hdrs[menu->current], M_DELETE, (i == OP_DELETE) ? 1 : 0);
PostCount = PostContext->msgcount - PostContext->deleted;
if (option (OPTRESOLVE) && menu->current < menu->max - 1)
{
menu->oldcurrent = menu->current;
menu->current++;
if (menu->current >= menu->top + menu->pagelen)
{
menu->top = menu->current;
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
}
else
menu->redraw |= REDRAW_MOTION_RESYNCH;
}
else
menu->redraw = REDRAW_CURRENT;
break;
case OP_GENERIC_SELECT_ENTRY:
r = menu->current;
done = 1;
break;
case OP_EXIT:
done = 1;
break;
}
}
mutt_menuDestroy (&menu);
return (r > -1 ? PostContext->hdrs[r] : NULL);
}
/* args:
* hdr envelope/attachment info for recalled message
* cur if message was a reply, `cur' is set to the message which
* `hdr' is in reply to
*
* return vals:
* -1 error/no messages
* 0 normal exit
* SENDREPLY recalled message is a reply
*/
int mutt_get_postponed (HEADER *hdr, HEADER **cur)
{
HEADER *h;
MESSAGE *msg;
int code = SENDPOSTPONED;
LIST *tmp;
LIST *last = NULL;
LIST *next;
char file[_POSIX_PATH_MAX];
char *p;
int opt_delete;
if ((PostContext = mx_open_mailbox (Postponed, M_NOSORT, NULL)) == NULL)
{
PostCount = 0;
mutt_error ("No postponed messages.");
return (-1);
}
if (! PostContext->msgcount)
{
PostCount = 0;
mx_close_mailbox (PostContext);
safe_free ((void **) &PostContext);
mutt_error ("No postponed messages.");
return (-1);
}
if (PostContext->msgcount == 1)
{
/* only one message, so just use that one. */
h = PostContext->hdrs[0];
}
else if ((h = select_msg ()) == NULL)
{
mx_close_mailbox (PostContext);
safe_free ((void **) &PostContext);
return (-1);
}
if ((msg = mx_open_message (PostContext, h->msgno)) == NULL)
{
mx_close_mailbox (PostContext);
safe_free ((void **) &PostContext);
return (-1);
}
fseek (msg->fp, h->offset, 0);
hdr->env = mutt_read_rfc822_header (msg->fp, NULL);
if (h->content->type == TYPEMESSAGE || h->content->type == TYPEMULTIPART)
{
BODY *b;
fseek (msg->fp, h->content->offset, 0);
if (h->content->type == TYPEMULTIPART)
{
h->content->parts = mutt_parse_multipart (msg->fp,
mutt_get_parameter ("boundary", h->content->parameter),
h->content->offset + h->content->length,
strcasecmp ("digest", h->content->subtype) == 0);
}
else
h->content->parts = mutt_parse_messageRFC822 (msg->fp, h->content);
/* Now that we know what was in the other message, convert to the new
* message.
*/
hdr->content = h->content->parts;
b = h->content->parts;
while (b != NULL)
{
file[0] = '\0';
if (b->filename)
strfcpy (file, b->filename, sizeof (file));
mutt_adv_mktemp (file);
if (mutt_save_attachment (msg->fp, b, file, 0) == -1)
{
mutt_free_envelope (&hdr->env);
mutt_free_body (&hdr->content);
mx_close_message (&msg);
mx_fastclose_mailbox (PostContext);
safe_free ((void **) &PostContext);
return (-1);
}
safe_free ((void *) &b->filename);
b->filename = safe_strdup (file);
b->unlink = 1;
mutt_free_body (&b->parts);
b = b->next;
}
h->content->parts = NULL;
}
else
{
mutt_mktemp (file);
if (mutt_save_attachment (msg->fp, h->content, file, 0) == -1)
{
mutt_free_envelope (&hdr->env);
mx_close_message (&msg);
mx_fastclose_mailbox (PostContext);
safe_free ((void **) &PostContext);
return (-1);
}
hdr->content = mutt_make_attach (file);
hdr->content->use_disp = 0; /* no content-disposition */
hdr->content->unlink = 1; /* delete when we are done */
}
mx_close_message (&msg);
/* finished with this message, so delete it. */
mutt_set_flag (PostContext, h, M_DELETE, 1);
/* update the count for the status display */
PostCount = PostContext->msgcount - PostContext->deleted;
/* avoid the "purge deleted messages" prompt */
opt_delete = quadoption (OPT_DELETE);
set_quadoption (OPT_DELETE, M_YES);
mx_close_mailbox (PostContext);
set_quadoption (OPT_DELETE, opt_delete);
safe_free ((void **) &PostContext);
for (tmp = hdr->env->userhdrs; tmp; )
{
if (Context && strncmp ("X-Mutt-References:", tmp->data, 18) == 0)
{
int j;
p = tmp->data + 18;
SKIPWS (p);
for (j=0; j < Context->msgcount; j++)
{
if (Context->hdrs[j]->env->message_id &&
strcmp (Context->hdrs[j]->env->message_id, p) == 0)
{
*cur = Context->hdrs[j];
break;
}
}
/* Remove the X-Mutt-References: header field. */
next = tmp->next;
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
if (*cur)
code |= SENDREPLY;
}
else
{
last = tmp;
tmp = tmp->ne